﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing.Design;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms.Design;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Converters;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using Ionic.Zip;
using MediaPad.Serialization;
using Microsoft.Win32;
using MediaPad.Implementation.Enums;
using MediaPad_2008.Implementation;

namespace MediaPad.Implementation
{
    internal class InkCanvasAdv : InkCanvas
    {
        #region Constants
        private const string DEFAULT_IMAGE_PATH = "pack://application:,,,/InkCanvasAdv;component/Resources/Images/DefaultImage.jpg";
        private const string DEFAULT_BUTTON_STYLE_PATH = "pack://application:,,,/InkCanvasAdv;component/Themes/Generic.xaml";

        internal const string DEF_IMAGE_FILTER = "Images (*.bmp;*.jpg;*.gif;*.png;*.tiff)|*.bmp;*.jpg;*.gif;*.png;*.tiff;";
        //private const string DEF_VIDEO_FILTER = "Video Files (*.3gp;*.asf;*.avi;*.flv;*.mov;*.mp4;*.mpg;*.wmv;)|*.3gp;*.asf;*.avi;*.flv;*.mov;*.mp4;*.mpg;*.wmv;";

        private const string DEF_AUDIO_FILTER = "Audio Files (*.m3u;*.mid;*.midi;*.mp3;*.m4a;*.wav;*.wma;)|*.m3u;*.mid;*.midi;*.mp3;*.m4a;*.wav;*.wma;*.mp2;*.mpa;";
        private const string DEF_VIDEO_FILTER = "Video Files (*.avi;*.wmv;*.mpg;*mpeg;*.m1v;*.mp2;*.mpa;*.3gp;*.asf;*.flv;*.mov;)|*.avi;*.wmv;*.mpg;*.mpeg;*.m1v;*.3gp;*.asf;*.flv;*.mov;";
        #endregion

        #region Private members
        public static readonly double widthCanvas = SystemParameters.PrimaryScreenWidth;
        public static readonly double heightCanvas = SystemParameters.PrimaryScreenHeight;

        private List<RichTextBox> m_selectedTextBoxes = new List<RichTextBox>();
        private string m_tempFile = null;
        private List<string> m_dirToDelete = new List<string>();
        private ImageBrush m_savedBrush;
        private RichTextBox m_lastFocusedTextbox = null;
        #endregion //Private members

        #region Initialization

        static InkCanvasAdv()
        {
            FrameworkPropertyMetadataOptions options = FrameworkPropertyMetadataOptions.Inherits |
                                                        FrameworkPropertyMetadataOptions.AffectsRender |
                                                        FrameworkPropertyMetadataOptions.AffectsMeasure;

            ItemFontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, options, new PropertyChangedCallback(OnItemFontFamilyChanged)));
            ItemFontSizeProperty = TextBlock.FontSizeProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(SystemFonts.MessageFontSize, options, new PropertyChangedCallback(OnItemFontSizeChanged)));
            ItemFontStretchProperty = TextBlock.FontStretchProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(FontStretches.Normal, options, new PropertyChangedCallback(OnItemFontStretchChanged)));
            ItemFontStyleProperty = TextBlock.FontStyleProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(SystemFonts.MessageFontStyle, options, new PropertyChangedCallback(OnItemFontStyleChanged)));
            ItemFontWeightProperty = TextBlock.FontWeightProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(SystemFonts.MessageFontWeight, options, new PropertyChangedCallback(OnItemFontWeightChanged)));
            ItemForegroundProperty = TextBlock.ForegroundProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(Brushes.Black,
                    FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender | FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender,
                    new PropertyChangedCallback(OnItemForegroundChanged)));
            ItemTextDecorationsProperty = TextBlock.TextDecorationsProperty.AddOwner(typeof(InkCanvasAdv),
                new FrameworkPropertyMetadata(new PropertyChangedCallback(OnItemTextDecorationsChanged)));

            MediaModeChangedEvent = EventManager.RegisterRoutedEvent("MediaModeChanged", RoutingStrategy.Bubble,
                typeof(InkCanvasAdvMediaModeChangedHandler), typeof(InkCanvasAdv));


        }

        public InkCanvasAdv()
            : base()
        {
            Loaded += new System.Windows.RoutedEventHandler(InkCanvasAdv_Loaded);
            Unloaded += new RoutedEventHandler(InkCanvasAdv_Unloaded);

            m_savedBrush = new ImageBrush();
            m_savedBrush.Stretch = Stretch.Fill;
            m_savedBrush.AlignmentX = AlignmentX.Left;
            m_savedBrush.AlignmentY = AlignmentY.Top;

            Cursor = Cursors.Pen;
            ForceCursor = true;
            EditingMode = InkCanvasEditingMode.Ink;

            m_tempFile = System.IO.Path.GetTempFileName();
        }
        #endregion //Initialization

        #region Events

        public static readonly RoutedEvent MediaModeChangedEvent;

        public event InkCanvasAdvMediaModeChangedHandler MediaModeChanged
        {
            add { AddHandler(MediaModeChangedEvent, value); }
            remove { RemoveHandler(MediaModeChangedEvent, value); }
        }

        #endregion //Events

        #region Properties

        /// <summary>
        /// Gets or sets FontFamily for textboxes
        /// </summary>
        public FontFamily ItemFontFamily
        {
            get
            {
                return (FontFamily)GetValue(ItemFontFamilyProperty);
            }
            set
            {
                SetValue(ItemFontFamilyProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets FontSize for textboxes
        /// </summary>
        public double ItemFontSize
        {
            get
            {
                return (double)GetValue(ItemFontSizeProperty);
            }
            set
            {
                SetValue(ItemFontSizeProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets FontStretch for textboxes
        /// </summary>
        public FontStretch ItemFontStretch
        {
            get
            {
                return (FontStretch)GetValue(ItemFontStretchProperty);
            }
            set
            {
                SetValue(ItemFontStretchProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets FontStyle for textboxes
        /// </summary>
        public FontStyle ItemFontStyle
        {
            get
            {
                return (FontStyle)GetValue(ItemFontStyleProperty);
            }
            set
            {
                SetValue(ItemFontStyleProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets FontWeight for textboxes
        /// </summary>
        public FontWeight ItemFontWeight
        {
            get
            {
                return (FontWeight)GetValue(ItemFontWeightProperty);
            }
            set
            {
                SetValue(ItemFontWeightProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets Foreground for textboxes
        /// </summary>
        public Brush ItemForeground
        {
            get
            {
                return (Brush)GetValue(ItemForegroundProperty);
            }
            set
            {
                SetValue(ItemForegroundProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets TextDecorations for textboxes
        /// </summary>
        public TextDecorationCollection ItemTextDecorations
        {
            get
            {
                return (TextDecorationCollection)GetValue(ItemTextDecorationsProperty);
            }
            set
            {
                SetValue(ItemTextDecorationsProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets active input media element type
        /// </summary>
        public InkCanvasAdvMediaMode MediaMode
        {
            get
            {
                return (InkCanvasAdvMediaMode)GetValue(MediaModeProperty);
            }
            set
            {
                SetValue(MediaModeProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets background image
        /// </summary>
        [Editor(typeof(ImageFileEditor), typeof(UITypeEditor))]
        public ImageSource BackgroundImage
        {
            get
            {
                return (ImageSource)GetValue(BackgroundImageProperty);
            }
            set
            {
                SetValue(BackgroundImageProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets rotation angle for the media elements
        /// </summary>
        public double MediaRotationAngle
        {
            get
            {
                return (double)GetValue(MediaRotationAngleProperty);
            }
            set
            {
                SetValue(MediaRotationAngleProperty, value);
            }
        }

        public InkCanvasAdvTextMode TextMode
        {
            get
            {
                return (InkCanvasAdvTextMode)GetValue(TextModeProperty);
            }
            set
            {
                SetValue(TextModeProperty, value);
            }
        }

        #endregion //Properties

        #region Dependency Properties

        public static readonly DependencyProperty ItemFontFamilyProperty;
        public static readonly DependencyProperty ItemFontSizeProperty;
        public static readonly DependencyProperty ItemFontStretchProperty;
        public static readonly DependencyProperty ItemFontStyleProperty;
        public static readonly DependencyProperty ItemFontWeightProperty;
        public static readonly DependencyProperty ItemForegroundProperty;
        public static readonly DependencyProperty ItemTextDecorationsProperty;

        public static readonly DependencyProperty MediaModeProperty =
            DependencyProperty.Register("MediaMode", typeof(InkCanvasAdvMediaMode), typeof(InkCanvasAdv),
                new PropertyMetadata(InkCanvasAdvMediaMode.None, new PropertyChangedCallback(OnMediaModeChanged)));

        public static readonly DependencyProperty BackgroundImageProperty =
            DependencyProperty.Register("BackgroundImage", typeof(ImageSource), typeof(InkCanvasAdv),
                new PropertyMetadata(null, new PropertyChangedCallback(OnBackgroundImageChanged)));

        public static readonly DependencyProperty MediaRotationAngleProperty =
            DependencyProperty.Register("MediaRotationAngle", typeof(double), typeof(InkCanvasAdv),
                new PropertyMetadata(0.0, new PropertyChangedCallback(OnMediaRotationAngleChanged)));

        public static readonly DependencyProperty TextModeProperty =
            DependencyProperty.Register("TextMode", typeof(InkCanvasAdvTextMode), typeof(InkCanvasAdv), new UIPropertyMetadata(InkCanvasAdvTextMode.Normal, OnTextModeChanged));

        #endregion //Dependency Properties

        #region Implementation

        #region Event Handlers

        static void OnItemFontFamilyChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.FontFamily = canvas.ItemFontFamily;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.FontFamily = canvas.ItemFontFamily;
            }
        }

        static void OnItemFontSizeChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.FontSize = canvas.ItemFontSize;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.FontSize = canvas.ItemFontSize;
            }
        }

        static void OnItemFontStretchChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.FontStretch = canvas.ItemFontStretch;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.FontStretch = canvas.ItemFontStretch;
            }
        }

        static void OnItemFontStyleChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.FontStyle = canvas.ItemFontStyle;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.FontStyle = canvas.ItemFontStyle;
            }
        }

        static void OnItemFontWeightChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.FontWeight = canvas.ItemFontWeight;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.FontWeight = canvas.ItemFontWeight;
            }
        }

        static void OnItemForegroundChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                canvas.m_lastFocusedTextbox.Foreground = canvas.ItemForeground;
                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                tb.Foreground = canvas.ItemForeground;
            }
        }

        static void OnItemTextDecorationsChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.m_lastFocusedTextbox != null)
            {
                foreach (Block b in canvas.m_lastFocusedTextbox.Document.Blocks)
                {
                    if (b is Paragraph)
                    {
                        ((Paragraph)b).TextDecorations = canvas.ItemTextDecorations;
                    }
                    else if (b is List)
                    {
                        foreach (ListItem listItem in ((List)b).ListItems)
                        {
                            foreach (Block listBlock in listItem.Blocks)
                            {
                                if (listBlock is Paragraph)
                                {
                                    ((Paragraph)listBlock).TextDecorations = canvas.ItemTextDecorations;
                                }
                            }
                        }
                    }
                }

                Keyboard.Focus(canvas.m_lastFocusedTextbox);
            }

            foreach (RichTextBox tb in canvas.GetSelectedTextBoxes())
            {
                foreach (Block b in tb.Document.Blocks)
                {
                    if (b is Paragraph)
                    {
                        ((Paragraph)b).TextDecorations = canvas.ItemTextDecorations;
                    }
                    else if (b is List)
                    {
                        foreach (ListItem listItem in ((List)b).ListItems)
                        {
                            foreach (Block listBlock in listItem.Blocks)
                            {
                                if (listBlock is Paragraph)
                                {
                                    ((Paragraph)listBlock).TextDecorations = canvas.ItemTextDecorations;
                                }
                            }
                        }
                    }
                }
            }
        }

        static void OnMediaModeChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.MediaMode == InkCanvasAdvMediaMode.None)
            {
                canvas.EditingMode = InkCanvasEditingMode.Select;
            }
            else
            {
                canvas.EditingMode = InkCanvasEditingMode.None;
            }

            if (canvas.MediaMode == InkCanvasAdvMediaMode.Text)
            {
                canvas.Cursor = Cursors.IBeam;
            }
            else if (canvas.MediaMode == InkCanvasAdvMediaMode.Image)
            {
                MemoryStream str = new MemoryStream(Properties.Resources.ImageCur);
                canvas.Cursor = new Cursor(str);
            }
            else if (canvas.MediaMode == InkCanvasAdvMediaMode.Video)
            {
                MemoryStream str = new MemoryStream(Properties.Resources.VideoCur);
                canvas.Cursor = new Cursor(str);
            }

            canvas.OnMediaModeChanged(new InkCanvasAdvMediaModeChangedArgs(MediaModeChangedEvent, canvas.MediaMode, null));
        }

        protected virtual void OnMediaModeChanged(InkCanvasAdvMediaModeChangedArgs e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            base.RaiseEvent(e);
        }

        protected override void OnEditingModeChanged(RoutedEventArgs e)
        {
            base.OnEditingModeChanged(e);

            if (EditingMode == InkCanvasEditingMode.Ink)
            {
                Cursor = Cursors.Pen;
            }
            else if (EditingMode == InkCanvasEditingMode.Select)
            {
                Cursor = Cursors.Cross;
            }
            else
            {
                Cursor = Cursors.Arrow;
            }

            if (EditingMode != InkCanvasEditingMode.None)
            {
                MediaMode = InkCanvasAdvMediaMode.None;
            }
        }

        static void OnBackgroundImageChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.BackgroundImage != null)
            {
                canvas.m_savedBrush.ImageSource = canvas.BackgroundImage;
                canvas.Background = canvas.m_savedBrush;
            }
        }

        static void OnMediaRotationAngleChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            RotateTransform tr = new RotateTransform();
            tr.Angle = canvas.MediaRotationAngle;

            foreach (UIElement ui in canvas.GetSelectedElements())
            {
                if (ui is FrameworkElement)
                {
                    ((FrameworkElement)ui).LayoutTransform = tr;
                }
            }
        }

        static void OnTextModeChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            InkCanvasAdv canvas = (InkCanvasAdv)sender;

            if (canvas.TextMode == InkCanvasAdvTextMode.Bullet)
            {
                canvas.CreateFlowDocumentList();
            }
            else
            {
                canvas.RemoveFlowDocumentList();
            }
        }

        private void CreateFlowDocumentList()
        {
            if (m_lastFocusedTextbox == null)
            {
                return;
            }

            int insertPos = -1;
            Paragraph paragraph = null;
            if (m_lastFocusedTextbox.CaretPosition != null && m_lastFocusedTextbox.CaretPosition.Paragraph != null)
            {
                paragraph = m_lastFocusedTextbox.CaretPosition.Paragraph;

                if (paragraph.Parent is ListItem)
                {
                    //ListItem already exists
                    return;
                }

                int i = 0;
                foreach (var block in m_lastFocusedTextbox.Document.Blocks)
                {
                    if (block == paragraph)
                    {
                        insertPos = i;
                        break;
                    }

                    i++;
                }
            }

            if (paragraph == null)
            {
                Run run = new Run();
                run.Text = string.Empty;

                paragraph = new Paragraph();
                paragraph.Inlines.Add(run);
            }

            List list = new List();
            list.MarkerOffset = 10;
            list.MarkerStyle = TextMarkerStyle.Box;
            list.ListItems.Add(new ListItem());

            if (insertPos >= 0)
            {
                m_lastFocusedTextbox.Document.Blocks.InsertBefore(paragraph, list);
                m_lastFocusedTextbox.Document.Blocks.Remove(paragraph);
            }
            else
            {
                m_lastFocusedTextbox.Document.Blocks.Add(list);
            }

            list.ListItems.LastListItem.Blocks.Add(paragraph);

            Keyboard.Focus(m_lastFocusedTextbox);
            if (paragraph.Inlines.Count > 0)
            {
                TextPointer moveTo = paragraph.Inlines.LastInline.ContentEnd;
                if (moveTo != null)
                {
                    m_lastFocusedTextbox.CaretPosition = moveTo;
                }
            }
        }

        private void RemoveFlowDocumentList()
        {
            if (m_lastFocusedTextbox == null)
            {
                return;
            }

            Paragraph paragraph = null;
            if (m_lastFocusedTextbox.CaretPosition != null && m_lastFocusedTextbox.CaretPosition.Paragraph != null)
            {
                paragraph = m_lastFocusedTextbox.CaretPosition.Paragraph;
            }

            if (paragraph != null && paragraph.Parent is ListItem)
            {
                ListItem listItem = (ListItem)paragraph.Parent;
                List list = (List)listItem.Parent;
                bool isFirst = (list.ListItems.FirstListItem == listItem);
                bool isLast = (list.ListItems.LastListItem == listItem);

                if (isFirst || isLast)
                {
                    Block prevBlock = list;
                    int count = listItem.Blocks.Count;
                    for (int i = 0; i < count; i++)
                    {
                        var block = listItem.Blocks.FirstBlock;
                        if (block != null)
                        {
                            listItem.Blocks.Remove(block);

                            if (isFirst)
                            {
                                m_lastFocusedTextbox.Document.Blocks.InsertBefore(list, block);
                            }
                            else
                            {
                                m_lastFocusedTextbox.Document.Blocks.InsertAfter(prevBlock, block);
                                prevBlock = block;
                            }
                        }
                    }

                    list.ListItems.Remove(listItem);
                    if (list.ListItems.Count == 0)
                    {
                        m_lastFocusedTextbox.Document.Blocks.Remove(list);
                    }
                }
                else
                {
                    List listBefore = new List();
                    List listAfter = new List();

                    bool reached = false;
                    int count = list.ListItems.Count;
                    for (int i = 0; i < count; i++)
                    {
                        var block = list.ListItems.FirstListItem;
                        if (block != null)
                        {
                            list.ListItems.Remove(block);

                            if (block == listItem)
                            {
                                reached = true;
                                continue;
                            }

                            if (!reached)
                            {
                                listBefore.ListItems.Add(block);
                            }
                            else
                            {
                                listAfter.ListItems.Add(block);
                            }
                        }
                    }

                    m_lastFocusedTextbox.Document.Blocks.InsertBefore(list, listBefore);

                    int cnt = listItem.Blocks.Count;
                    for (int i = 0; i < cnt; i++)
                    {
                        var block = listItem.Blocks.FirstBlock;
                        if (block != null)
                        {
                            listItem.Blocks.Remove(block);
                            m_lastFocusedTextbox.Document.Blocks.InsertBefore(list, block);
                        }
                    }

                    m_lastFocusedTextbox.Document.Blocks.InsertAfter(list, listAfter);
                    m_lastFocusedTextbox.Document.Blocks.Remove(list);
                }
            }

            Keyboard.Focus(m_lastFocusedTextbox);
            if (paragraph.Inlines.Count > 0)
            {
                TextPointer moveTo = paragraph.Inlines.LastInline.ContentEnd;

                if (moveTo != null)
                {
                    m_lastFocusedTextbox.CaretPosition = moveTo;
                }
            }
        }

        void InkCanvasAdv_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            AllowDrop = true;
            MoveEnabled = true;
            ResizeEnabled = true;

            //DrawDefaultInkCanvas();

            PreviewDrop += new System.Windows.DragEventHandler(InkCanvasAdv_PreviewDrop);
            PreviewDragOver += new System.Windows.DragEventHandler(InkCanvasAdv_PreviewDragOver);
            MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(InkCanvasAdv_MouseLeftButtonDown);
            SelectionChanged += new EventHandler(InkCanvasAdv_SelectionChanged);

            SetValue(TextBlock.FontFamilyProperty, new FontFamily("Arial"));

            TextDecorationCollection col = new TextDecorationCollection();
            ItemTextDecorations = col;
        }

        void InkCanvasAdv_Unloaded(object sender, RoutedEventArgs e)
        {
            ClearChildren();
            File.Delete(m_tempFile);
        }

        void InkCanvasAdv_SelectionChanged(object sender, EventArgs e)
        {
            m_selectedTextBoxes.Clear();

            ReadOnlyCollection<UIElement> coll = GetSelectedElements();
            foreach (UIElement el in coll)
            {
                if (el is RichTextBox)
                {
                    RichTextBox tb = el as RichTextBox;
                    Canvas.SetLeft(tb, tb.Margin.Left);
                    Canvas.SetTop(tb, tb.Margin.Top);

                    m_selectedTextBoxes.Add(tb);
                }
            }
        }

        void InkCanvasAdv_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (EditingMode == InkCanvasEditingMode.None)
            {
                switch (MediaMode)
                {
                    case InkCanvasAdvMediaMode.Text:

                        CreateTextBox();
                        break;
                    case InkCanvasAdvMediaMode.Image:

                        CreateImage();
                        break;
                    case InkCanvasAdvMediaMode.Video:

                        CreateMediaPlayer();
                        break;
                }
            }
        }

        void InkCanvasAdv_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
        {
            e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop)
                ? DragDropEffects.All : DragDropEffects.None;
        }

        void InkCanvasAdv_PreviewDrop(object sender, System.Windows.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];

                if (files != null && files.Length > 0)
                {
                    string filePath = files[0];
                    string extention = System.IO.Path.GetExtension(filePath).ToLower();

                    if (DEF_IMAGE_FILTER.Contains(extention.ToLower()))
                    {
                        CreateImage(filePath);
                    }
                    else if (DEF_VIDEO_FILTER.Contains(extention.ToLower()) || DEF_AUDIO_FILTER.Contains(extention.ToLower()))
                    {
                        CreateMediaPlayer(filePath);
                    }
                }
            }
        }

        void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = GetParentGrid(sender as DependencyObject, 1);
            if (grid != null)
            {
                MediaElement el = (MediaElement)grid.DataContext;
                try
                {
                    el.Play();
                }
                catch (Exception)
                {
                    MessageBox.Show("Cannot open current file. Check if required video codecs are installed");
                }
            }
        }

        void btnPause_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = GetParentGrid(sender as DependencyObject, 1);
            if (grid != null)
            {
                MediaElement el = (MediaElement)grid.DataContext;
                if (el.CanPause)
                {
                    el.Pause();
                }
                else
                {
                    MessageBox.Show("Current media cannot be paused");
                }
            }
        }

        void btnStop_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = GetParentGrid(sender as DependencyObject, 1);
            if (grid != null)
            {
                MediaElement el = (MediaElement)grid.DataContext;
                el.Stop();

                string extension = el.Source.IsAbsoluteUri ? System.IO.Path.GetExtension(el.Source.LocalPath) :
                                                        System.IO.Path.GetExtension(el.Source.OriginalString);
                if (DEF_VIDEO_FILTER.Contains(extension.ToLower()))
                {
                    ShowVideoFirstFrame(el);
                }
            }
        }

        void btnClose_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = GetParentGrid(sender as DependencyObject, 1);
            if (grid != null)
            {
                MediaElement el = (MediaElement)grid.DataContext;
                el.Stop();
                el.Source = null;

                Children.Remove(grid);
            }
        }

        void btnSource_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = false;
            dlg.Filter = DEF_AUDIO_FILTER + "|" + DEF_VIDEO_FILTER;

            if (dlg.ShowDialog().Value)
            {
                Grid grid = GetParentGrid(sender as DependencyObject, 2);
                if (grid != null)
                {
                    MediaElement el = (MediaElement)grid.DataContext;
                    el.Source = new Uri(dlg.FileName);
                    el.Unloaded += new RoutedEventHandler(el_Unloaded);

                    Image im = null;
                    foreach (object obj in grid.Children)
                    {
                        if (obj is Image)
                        {
                            im = (Image)obj;
                        }
                        else if (obj is Grid)
                        {
                            foreach (Button btn in ((Grid)obj).Children)
                            {
                                if (btn.Name == "Play" || btn.Name == "Pause" || btn.Name == "Stop")
                                {
                                    btn.Visibility = Visibility.Visible;
                                }
                            }
                        }
                    }

                    string extension = System.IO.Path.GetExtension(dlg.FileName);
                    if (DEF_VIDEO_FILTER.Contains(extension.ToLower()))
                    {
                        ShowVideoFirstFrame(el);

                        if (im != null)
                        {
                            im.Visibility = Visibility.Collapsed;
                        }
                    }
                    else if (im != null)
                    {
                        im.Visibility = Visibility.Visible;
                    }
                }
            }
        }

        void el_Loaded(object sender, RoutedEventArgs e)
        {
            MediaElement el = (MediaElement)sender;
            if (el.Source == null)
                return;

            ShowVideoFirstFrame(el);
        }

        private void ShowVideoFirstFrame(MediaElement el)
        {
            try
            {
                el.Play();
                Thread.Sleep(100);
                el.Pause();
            }
            catch (Win32Exception)
            {
                MessageBox.Show("Cannot open current file. Check if required video codecs are installed. Note: Windows Media Player have to be installed on your PC.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void el_Unloaded(object sender, RoutedEventArgs e)
        {
            MediaElement el = (MediaElement)sender;
            if (el.Source == null)
                return;

            el.Stop();
        }

        void im_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = false;
            dlg.Filter = DEF_IMAGE_FILTER;

            if (dlg.ShowDialog().Value)
            {
                Image im = (Image)sender;
                BitmapImage bm = new BitmapImage();
                bm.BeginInit();
                bm.UriSource = new Uri(dlg.FileName);
                bm.CacheOption = BitmapCacheOption.OnLoad;
                bm.EndInit();

                im.Source = bm;
            }
        }

        void tbBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            RichTextBox tb = (RichTextBox)sender;
            m_lastFocusedTextbox = tb;
        }

        void tbBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            RichTextBox tb = (RichTextBox)sender;

            if (tb.Document.Blocks == null || tb.Document.Blocks.Count == 0 ||
                (tb.Document.Blocks.FirstBlock is Paragraph &&
                ((Paragraph)tb.Document.Blocks.FirstBlock).Inlines.Count == 0 &&
                tb.Document.Blocks.FirstBlock == tb.Document.Blocks.LastBlock))
            {
                InkCanvas parent = tb.Parent as InkCanvas;
                parent.Children.Remove(tb);

                m_lastFocusedTextbox = null;
            }

            if (IsKeyboardFocused || IsKeyboardFocusWithin)
            {
                m_lastFocusedTextbox = null;
            }
        }

        #endregion //Event Handlers

        private List<RichTextBox> GetSelectedTextBoxes()
        {
            return m_selectedTextBoxes;
        }

        private void CreateTextBox()
        {
            SetMediaMode(InkCanvasAdvMediaMode.Text);

            RichTextBox tbBox = new RichTextBox();
            tbBox.MinWidth = 200;
            this.ItemFontSize = 24;
            tbBox.BorderThickness = new Thickness(0);
            tbBox.Background = Brushes.Transparent;
            tbBox.AcceptsReturn = true;
            tbBox.LayoutTransform = new RotateTransform(MediaRotationAngle);

            SetTextBoxValues(tbBox);

            Point position = Mouse.GetPosition(this);
            InkCanvas.SetLeft(tbBox, position.X);
            InkCanvas.SetTop(tbBox, position.Y);

            tbBox.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(tbBox_GotKeyboardFocus);
            tbBox.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(tbBox_LostKeyboardFocus);

            Children.Add(tbBox);
            Keyboard.Focus(tbBox);

            if (TextMode == InkCanvasAdvTextMode.Bullet)
            {
                CreateFlowDocumentList();
            }
        }

        private void CreateTextBox(SerializationTextBoxInfo ii)
        {
            SetMediaMode(InkCanvasAdvMediaMode.Text);

            RichTextBox tbBox = new RichTextBox();
            tbBox.MinWidth = 200;
            tbBox.Width = ii.Size.Width;
            tbBox.Height = ii.Size.Height;
            tbBox.LayoutTransform = new RotateTransform(ii.MediaRotationAngle);
            tbBox.BorderThickness = new Thickness(0);
            tbBox.Background = Brushes.Transparent;
            tbBox.AcceptsReturn = true;

            string data = ii.Text;
            using (TextReader stringReader = new StringReader(data))
            {
                using (XmlReader xmlReader = new XmlTextReader(stringReader))
                {
                    tbBox.Document = (FlowDocument)XamlReader.Load(xmlReader);
                }
            }

            tbBox.FontFamily = new FontFamily(ii.FontFamilyName);
            tbBox.FontSize = ii.FontSize;
            tbBox.FontStyle = (ii.FontStyle == 0 ? FontStyles.Normal :
                                                    (ii.FontStyle == 1 ? FontStyles.Oblique : FontStyles.Italic));
            tbBox.FontWeight = (ii.FontWeight == 700 ? FontWeights.Bold : FontWeights.Normal);
            tbBox.FontStretch = FontStretch.FromOpenTypeStretch(ii.FontStretch);

            BrushValueSerializer ser = new BrushValueSerializer();
            if (ser.CanConvertFromString(ii.Foreground, null))
            {
                tbBox.Foreground = (Brush)ser.ConvertFromString(ii.Foreground, null);
            }

            TextDecorationCollection col = new TextDecorationCollection();
            foreach (int i in ii.TextDecorations)
            {
                TextDecorationLocation loc;
                switch (i)
                {
                    case 0:
                        loc = TextDecorationLocation.Underline;
                        break;
                    case 1:
                        loc = TextDecorationLocation.OverLine;
                        break;
                    case 2:
                        loc = TextDecorationLocation.Strikethrough;
                        break;
                    default:
                        loc = TextDecorationLocation.Baseline;
                        break;
                }

                col.Add(new TextDecoration(loc, new Pen(Brushes.Black, 1.0), 0.0, TextDecorationUnit.Pixel, TextDecorationUnit.Pixel));
            }

            foreach (Block b in tbBox.Document.Blocks)
            {
                if (b is Paragraph)
                {
                    ((Paragraph)b).TextDecorations = col;
                }
                else if (b is List)
                {
                    foreach (ListItem listItem in ((List)b).ListItems)
                    {
                        foreach (Block listBlock in listItem.Blocks)
                        {
                            if (listBlock is Paragraph)
                            {
                                ((Paragraph)listBlock).TextDecorations = col;
                            }
                        }
                    }
                }
            }

            InkCanvas.SetLeft(tbBox, ii.CanvasX);
            InkCanvas.SetTop(tbBox, ii.CanvasY);

            tbBox.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(tbBox_GotKeyboardFocus);
            tbBox.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(tbBox_LostKeyboardFocus);

            Children.Add(tbBox);
            Keyboard.Focus(tbBox);
        }

        private void SetTextBoxValues(RichTextBox tb)
        {
            tb.FontFamily = (FontFamily)GetValue(ItemFontFamilyProperty);
            tb.FontSize = (double)GetValue(ItemFontSizeProperty);
            tb.FontStretch = (FontStretch)GetValue(ItemFontStretchProperty);
            tb.FontStyle = (FontStyle)GetValue(ItemFontStyleProperty);
            tb.FontWeight = (FontWeight)GetValue(ItemFontWeightProperty);
            tb.Foreground = (Brush)GetValue(ItemForegroundProperty);

            TextDecorationCollection col = (TextDecorationCollection)GetValue(ItemTextDecorationsProperty);
            foreach (Block b in tb.Document.Blocks)
            {
                if (b is Paragraph)
                {
                    ((Paragraph)b).TextDecorations = col;
                }
                else if (b is List)
                {
                    foreach (ListItem listItem in ((List)b).ListItems)
                    {
                        foreach (Block listBlock in listItem.Blocks)
                        {
                            if (listBlock is Paragraph)
                            {
                                ((Paragraph)listBlock).TextDecorations = col;
                            }
                        }
                    }
                }
            }
        }

        private Image CreateImage()
        {
            SetMediaMode(InkCanvasAdvMediaMode.Image);

            Image im = new Image();
            im.Width = 200;
            im.Height = 150;
            im.LayoutTransform = new RotateTransform(MediaRotationAngle);

            BitmapImage bm = new BitmapImage();
            bm.BeginInit();
            bm.UriSource = new Uri(DEFAULT_IMAGE_PATH);
            bm.CacheOption = BitmapCacheOption.OnLoad;
            bm.EndInit();

            im.Source = bm;
            im.Effect = new DropShadowEffect();

            im.MouseLeftButtonDown += new MouseButtonEventHandler(im_MouseLeftButtonDown);

            Point position = Mouse.GetPosition(this);
            InkCanvas.SetLeft(im, position.X);
            InkCanvas.SetTop(im, position.Y);

            Children.Add(im);
            SetEditingMode(InkCanvasEditingMode.Select);

            List<UIElement> list = new List<UIElement>();
            list.Add(im);
            Select(list);

            return im;
        }

        private Image CreateImage(string filePath)
        {
            SetMediaMode(InkCanvasAdvMediaMode.Image);

            Image im = new Image();
            im.Width = 200;
            im.Height = 150;
            im.LayoutTransform = new RotateTransform(MediaRotationAngle);

            string path = File.Exists(filePath) ? filePath : DEFAULT_IMAGE_PATH;

            BitmapImage bm = new BitmapImage();
            bm.BeginInit();
            bm.UriSource = new Uri(path);
            bm.CacheOption = BitmapCacheOption.OnLoad;
            bm.EndInit();

            im.Source = bm;
            im.Effect = new DropShadowEffect();

            im.MouseLeftButtonDown += new MouseButtonEventHandler(im_MouseLeftButtonDown);

            Point position = Mouse.GetPosition(this);
            InkCanvas.SetLeft(im, position.X);
            InkCanvas.SetTop(im, position.Y);

            Children.Add(im);
            SetEditingMode(InkCanvasEditingMode.Select);

            List<UIElement> list = new List<UIElement>();
            list.Add(im);
            Select(list);

            return im;
        }

        private Image CreateImage(SerializationBaseInfo info, string directory)
        {
            SetMediaMode(InkCanvasAdvMediaMode.Image);

            Image im = new Image();
            im.Width = info.Size.Width;
            im.Height = info.Size.Height;
            im.LayoutTransform = new RotateTransform(info.MediaRotationAngle);

            string filePath = System.IO.Path.Combine(directory, System.IO.Path.GetFileName(info.FilePath.LocalPath));
            filePath = File.Exists(filePath) ? filePath : DEFAULT_IMAGE_PATH;

            BitmapImage bm = new BitmapImage();
            bm.BeginInit();
            bm.UriSource = new Uri(filePath);
            bm.CacheOption = BitmapCacheOption.OnLoad;
            bm.EndInit();

            im.Source = bm;
            im.Effect = new DropShadowEffect();

            im.MouseLeftButtonDown += new MouseButtonEventHandler(im_MouseLeftButtonDown);

            InkCanvas.SetLeft(im, info.CanvasX);
            InkCanvas.SetTop(im, info.CanvasY);

            Children.Add(im);
            SetEditingMode(InkCanvasEditingMode.Select);

            List<UIElement> list = new List<UIElement>();
            list.Add(im);
            Select(list);

            return im;
        }

        private MediaElement CreateMediaPlayer()
        {
            SetMediaMode(InkCanvasAdvMediaMode.Video);

            MediaElement pl = new MediaElement();
            pl.Name = "Video";
            pl.MinWidth = 250;
            pl.MinHeight = 200;
            pl.LayoutTransform = new RotateTransform(MediaRotationAngle);

            pl.LoadedBehavior = MediaState.Manual;
            pl.UnloadedBehavior = MediaState.Manual;

            Grid grid = CreateMediaGrid(pl);

            Point position = Mouse.GetPosition(this);
            InkCanvas.SetLeft(grid, position.X);
            InkCanvas.SetTop(grid, position.Y);

            Children.Add(grid);
            SetEditingMode(InkCanvasEditingMode.Select);

            List<UIElement> list = new List<UIElement>();
            list.Add(grid);
            Select(list);

            return pl;
        }

        private Grid CreateMediaGrid(MediaElement pl)
        {
            Grid grid = new Grid();
            grid.DataContext = pl;
            grid.Width = 200;
            grid.Height = 150;//W:H=4:3
            grid.MinWidth = 200;
            grid.MinHeight = 150;

            pl.Margin = new Thickness(10);

            Uri uri = new Uri(DEFAULT_BUTTON_STYLE_PATH);
            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = uri;
            Style btnRoundStyle = (Style)dict["MediaRoundButtonStyle"];

            Button btnClose = new Button();
            btnClose.FontFamily = new FontFamily("Calibri");
            btnClose.Name = "Close";
            btnClose.Content = "X";
            btnClose.Style = btnRoundStyle;
            btnClose.HorizontalAlignment = HorizontalAlignment.Right;
            btnClose.VerticalAlignment = VerticalAlignment.Top;
            btnClose.Click += new RoutedEventHandler(btnClose_Click);

            grid.Children.Add(pl);
            grid.Children.Add(CreateMediaBackgroundImage());
            grid.Children.Add(btnClose);
            grid.Children.Add(CreateMediaButtons());

            return grid;
        }

        private MediaElement CreateMediaPlayer(string filePath)
        {
            SetMediaMode(InkCanvasAdvMediaMode.Video);

            MediaElement el = CreateMediaPlayer();
            if (File.Exists(filePath))
            {
                el.Source = new Uri(filePath);
                el.Loaded += new RoutedEventHandler(el_Loaded);
                el.Unloaded += new RoutedEventHandler(el_Unloaded);

                Grid grid = GetParentGrid(el as DependencyObject, 1);
                if (grid != null)
                {
                    Image im = null;
                    foreach (object obj in grid.Children)
                    {
                        if (obj is Image)
                        {
                            im = (Image)obj;
                        }
                        else if (obj is Grid)
                        {
                            foreach (Button btn in ((Grid)obj).Children)
                            {
                                if (btn.Name == "Play" || btn.Name == "Pause" || btn.Name == "Stop")
                                {
                                    btn.Visibility = Visibility.Visible;
                                }
                            }
                        }
                    }

                    string extension = el.Source.IsAbsoluteUri ? System.IO.Path.GetExtension(el.Source.LocalPath) :
                                                        System.IO.Path.GetExtension(el.Source.OriginalString);
                    if (DEF_VIDEO_FILTER.Contains(extension.ToLower()))
                    {
                        ShowVideoFirstFrame(el);

                        if (im != null)
                        {
                            im.Visibility = Visibility.Collapsed;
                        }
                    }
                    else if (im != null)
                    {
                        im.Visibility = Visibility.Visible;
                    }
                }
            }

            return el;
        }

        private MediaElement CreateMediaPlayer(SerializationBaseInfo info, string directory)
        {
            SetMediaMode(InkCanvasAdvMediaMode.Video);

            MediaElement pl = new MediaElement();
            pl.Name = "Video";
            pl.MinWidth = 200;
            pl.MinHeight = 150;
            pl.Margin = new Thickness(10);
            pl.LayoutTransform = new RotateTransform(info.MediaRotationAngle);

            pl.LoadedBehavior = MediaState.Manual;
            pl.UnloadedBehavior = MediaState.Manual;

            Grid grid = new Grid();
            grid.DataContext = pl;
            grid.Width = info.Size.Width;
            grid.Height = info.Size.Height;
            //grid.Effect = new DropShadowEffect();

            Uri uri = new Uri(DEFAULT_BUTTON_STYLE_PATH);
            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = uri;
            Style btnRoundStyle = (Style)dict["MediaRoundButtonStyle"];

            Button btnClose = new Button();
            btnClose.FontFamily = new FontFamily("Calibri");
            btnClose.Name = "Close";
            btnClose.Content = "X";
            btnClose.Style = btnRoundStyle;
            btnClose.HorizontalAlignment = HorizontalAlignment.Right;
            btnClose.VerticalAlignment = VerticalAlignment.Top;
            btnClose.Click += new RoutedEventHandler(btnClose_Click);

            grid.Children.Add(pl);
            grid.Children.Add(CreateMediaBackgroundImage());
            grid.Children.Add(btnClose);
            grid.Children.Add(CreateMediaButtons());

            InkCanvas.SetLeft(grid, info.CanvasX);
            InkCanvas.SetTop(grid, info.CanvasY);

            string filePath = System.IO.Path.Combine(directory, System.IO.Path.GetFileName(info.FilePath.LocalPath));
            filePath = File.Exists(filePath) ? filePath : string.Empty;

            if (!string.IsNullOrEmpty(filePath))
            {
                pl.Source = new Uri(filePath);
                pl.Loaded += new RoutedEventHandler(el_Loaded);
                pl.Unloaded += new RoutedEventHandler(el_Unloaded);

                Image im = null;
                foreach (object obj in grid.Children)
                {
                    if (obj is Image)
                    {
                        im = (Image)obj;
                    }
                    else if (obj is Grid)
                    {
                        foreach (Button btn in ((Grid)obj).Children)
                        {
                            if (btn.Name == "Play" || btn.Name == "Pause" || btn.Name == "Stop")
                            {
                                btn.Visibility = Visibility.Visible;
                            }
                        }
                    }
                }

                string extension = pl.Source.IsAbsoluteUri ? System.IO.Path.GetExtension(pl.Source.LocalPath) :
                                                    System.IO.Path.GetExtension(pl.Source.OriginalString);
                if (DEF_VIDEO_FILTER.Contains(extension.ToLower()))
                {
                    ShowVideoFirstFrame(pl);

                    if (im != null)
                    {
                        im.Visibility = Visibility.Collapsed;
                    }
                }
                else if (im != null)
                {
                    im.Visibility = Visibility.Visible;
                }
            }

            Children.Add(grid);
            SetEditingMode(InkCanvasEditingMode.Select);

            List<UIElement> list = new List<UIElement>();
            list.Add(grid);
            Select(list);

            return pl;
        }

        private Image CreateMediaBackgroundImage()
        {
            BitmapImage bm = new BitmapImage();
            bm.BeginInit();
            bm.UriSource = new Uri(DEFAULT_IMAGE_PATH);
            bm.CacheOption = BitmapCacheOption.OnLoad;
            bm.EndInit();

            Image im = new Image();
            im.Name = "mediaBackgroundImage";
            im.Margin = new Thickness(10);
            im.LayoutTransform = new RotateTransform(MediaRotationAngle);
            im.Source = bm;

            return im;
        }

        private Grid CreateMediaButtons()
        {
            Uri uri = new Uri(DEFAULT_BUTTON_STYLE_PATH);
            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = uri;

            Style btnStyle = (Style)dict["MediaButtonStyle"];
            Style btnRoundStyle = (Style)dict["MediaRoundButtonStyle"];

            Button btnPlay = new Button();
            btnPlay.Name = "Play";
            btnPlay.FontFamily = new FontFamily("Webdings");
            btnPlay.Content = "4";
            btnPlay.Style = btnStyle;
            btnPlay.Click += new RoutedEventHandler(btnPlay_Click);

            Button btnPause = new Button();
            btnPause.Name = "Pause";
            btnPause.FontFamily = new FontFamily("Webdings");
            btnPause.Content = ";";
            btnPause.Style = btnStyle;
            btnPause.Click += new RoutedEventHandler(btnPause_Click);

            Button btnStop = new Button();
            btnStop.Name = "Stop";
            btnStop.FontFamily = new FontFamily("Webdings");
            btnStop.Content = "<";
            btnStop.Style = btnStyle;
            btnStop.Click += new RoutedEventHandler(btnStop_Click);

            Button btnSource = new Button();
            btnSource.FontFamily = new FontFamily("Webdings");
            btnSource.Name = "Source";
            btnSource.Content = "6";
            btnSource.Style = btnRoundStyle;
            btnSource.Click += new RoutedEventHandler(btnSource_Click);

            Grid panel = new Grid();
            panel.HorizontalAlignment = HorizontalAlignment.Right;
            panel.VerticalAlignment = VerticalAlignment.Bottom;
            panel.ColumnDefinitions.Add(new ColumnDefinition());
            panel.ColumnDefinitions.Add(new ColumnDefinition());
            panel.ColumnDefinitions.Add(new ColumnDefinition());
            panel.ColumnDefinitions.Add(new ColumnDefinition());

            btnPlay.SetValue(Grid.ColumnProperty, 0);
            btnPause.SetValue(Grid.ColumnProperty, 1);
            btnStop.SetValue(Grid.ColumnProperty, 2);
            btnSource.SetValue(Grid.ColumnProperty, 3);

            panel.Children.Add(btnPlay);
            panel.Children.Add(btnPause);
            panel.Children.Add(btnStop);
            panel.Children.Add(btnSource);

            return panel;
        }

        private void SetMediaMode(InkCanvasAdvMediaMode mode)
        {
            MediaMode = mode;
        }

        private void SetEditingMode(InkCanvasEditingMode mode)
        {
            EditingMode = mode;
        }

        private Grid GetParentGrid(DependencyObject visual, int level)
        {
            int l = 1;
            Grid grid = null;
            while (grid == null && visual != null)
            {
                visual = VisualTreeHelper.GetParent(visual);
                if (visual is Grid)
                {
                    if (l == level)
                    {
                        grid = (Grid)visual;
                    }
                    else
                    {
                        l++;
                    }
                }
            }

            return grid;
        }

        private void RemoveChildrenAndRedrwDefault()
        {
            foreach (UIElement ui in Children)
            {
                if (ui is Image)
                {
                    Image im = ui as Image;
                    BitmapImage b = (BitmapImage)im.Source;
                    b.ClearValue(BitmapImage.UriSourceProperty);
                    im.ClearValue(Image.SourceProperty);
                    b = null;
                }
                else if (ui is Grid)
                {
                    Grid grid = ui as Grid;
                    MediaElement me = (MediaElement)grid.DataContext;
                    me.Stop();
                    me.Close();
                    me.ClearValue(MediaElement.SourceProperty);
                }
            }

            Children.Clear();
            //RemoveChildrenAndRedrwDefault();
        }

        private void RemoveResources()
        {
            RemoveFilesAsinc();

            //Do not delete this.
            //time for deleting files is needed.
            //then delete directories
            Thread.Sleep(500);

            for (int i = 0; i < m_dirToDelete.Count; i++)
            {
                string directory = m_dirToDelete[i];
                Directory.Delete(directory, true);
            }

            m_dirToDelete.Clear();
        }

        private void RemoveFilesAsinc()
        {
            for (int i = 0; i < m_dirToDelete.Count; i++)
            {
                string directory = m_dirToDelete[i];

                DirectoryInfo dInfo = Directory.CreateDirectory(directory);
                FileInfo[] fInfo = dInfo.GetFiles();

                for (int j = 0; j < fInfo.Length; j++)
                {
                    FileInfo fi = fInfo[j];
                    File.Delete(fi.FullName);
                }
            }
        }

        private void DrawDefaultInkCanvas()
        {
            Background = new SolidColorBrush(Color.FromRgb(238, 245, 137));

            //Draw blue horizontal lines 1/4 inch apart.
            double y = 24;

            Binding widthBinding = new Binding();
            widthBinding.Path = new PropertyPath(ActualWidthProperty);
            widthBinding.Source = this;

            Binding heightBinding = new Binding();
            heightBinding.Path = new PropertyPath(ActualHeightProperty);
            heightBinding.Source = this;

            while (y < heightCanvas)
            {
                Line line = new Line();
                line.X1 = 0;
                line.Y1 = y;
                line.SetBinding(Line.X2Property, widthBinding);
                line.Y2 = y;
                line.Stroke = Brushes.LightBlue;
                Children.Add(line);

                y += 24;
            }

            Line line1 = new Line();
            line1.Stroke = Brushes.Red;
            line1.X1 = 35;
            line1.Y1 = 0;
            line1.X2 = 35;
            line1.SetBinding(Line.Y2Property, heightBinding);

            Line line2 = new Line();
            line2.Stroke = Brushes.Red;
            line2.X1 = 45;
            line2.Y1 = 0;
            line2.X2 = 45;
            line2.SetBinding(Line.Y2Property, heightBinding);

            Children.Add(line1);
            Children.Add(line2);
        }

        public void RemoveSelection()
        {
            if (GetSelectedStrokes().Count > 0)
            {
                foreach (Stroke strk in GetSelectedStrokes())
                    Strokes.Remove(strk);
            }

            if (GetSelectedElements().Count > 0)
            {
                for (int i = 0; i < GetSelectedElements().Count; i++)
                {
                    UIElement el = GetSelectedElements()[i];
                    Children.Remove(el);
                    i--;
                }
            }
        }

        public void RemoveAll()
        {
            ClearChildren();
        }

        private void ClearChildren()
        {
            Strokes.Clear();
            RemoveChildrenAndRedrwDefault();

            RemoveResources();
        }

        public void SelectAll()
        {
            Select(Strokes);

            List<UIElement> list = new List<UIElement>();
            foreach (UIElement ui in Children)
            {
                list.Add(ui);
            }

            Select(list);
        }

        public void Open()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.CheckFileExists = true;
            dlg.Filter = "Ink Serialized Format (*.isf)|*.isf|" +
                         "Binary files (*.pak)|*.pak|" +
                         "All files (*.*)|*.*";

            if ((bool)dlg.ShowDialog())
            {
                Open(dlg.FileName);
            }
        }

        /// <summary>
        /// Opens specified file.
        /// </summary>
        /// <param name="fileName">*pak,*.isf files are supported.</param>
        public void Open(string fileName)
        {
            ClearChildren();

            string directory = "";
            string datFile = "";

            try
            {
                if (fileName.ToLower().EndsWith(".pak"))
                {
                    string dirName = Directory.GetParent(m_tempFile).FullName;
                    string fileNameWithoutExt = System.IO.Path.GetFileNameWithoutExtension(fileName);

                    ZipFile zipFile = new ZipFile(fileName);
                    zipFile.ExtractAll(dirName, ExtractExistingFileAction.OverwriteSilently);

                    datFile = dirName + "\\" + fileNameWithoutExt + ".dat";
                    directory = dirName + "\\" + System.IO.Path.GetFileNameWithoutExtension(fileName);

                    InkCanvasSerializationInfo info = Serializer.DeSerializeObject(datFile);
                    SetSavedInfo(info, directory);

                    zipFile.Dispose();
                    File.Delete(datFile);
                    m_dirToDelete.Add(directory);
                }
                else
                {
                    using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                    {
                        if (fileName.ToLower().EndsWith(".isf"))
                        {
                            Strokes = new StrokeCollection(file);
                        }
                        else
                        {
                            MessageBox.Show("The requested file is not a Ink Serialized Format file\r\n\r\nplease retry", "");
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                if (fileName.ToLower().EndsWith(".pak"))
                {
                    DirectoryInfo dInfo = Directory.CreateDirectory(directory);

                    FileInfo[] fInfo = dInfo.GetFiles();

                    for (int j = 0; j < fInfo.Length; j++)
                    {
                        FileInfo fi = fInfo[j];
                        File.Delete(fi.FullName);
                    }

                    //Do not delete this.
                    //time for deleting files is needed.
                    //then delete directories
                    Thread.Sleep(300);

                    File.Delete(datFile);
                    Directory.Delete(dInfo.FullName);
                }

                MessageBox.Show(exc.Message, "");
            }
        }

        public void Save()
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Ink Serialized Format (*.isf)|*.isf|" +
                         "Binary files (*.pak)|*.pak|" +
                         "Bitmap files (*.bmp)|*.bmp|" +
                         "All files (*.*)|*.*";

            if ((bool)dlg.ShowDialog())
            {
                Save(dlg.FileName);
            }
        }

        /// <summary>
        /// Saves data to file.
        /// </summary>
        /// <param name="fileName">*.pak,*.isf,*.bmp files are supported.</param>
        public void Save(string fileName)
        {
            DirectoryInfo dInfo = null;
            string extension = System.IO.Path.GetExtension(fileName);

            try
            {
                if (extension.Contains("pak"))
                {
                    bool deleteFolder;

                    string dirName = Directory.GetParent(m_tempFile).FullName;

                    dInfo = Directory.CreateDirectory(dirName + "\\" + System.IO.Path.GetFileNameWithoutExtension(fileName));
                    InkCanvasSerializationInfo info = GetInkCanvasSerializationInfo(dInfo, out deleteFolder);
                    Serializer.SerializeObject(fileName, info, deleteFolder, m_tempFile);
                }
                else
                {
                    using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                    {
                        //Ink Serialized Format
                        if (extension.Contains("isf"))
                        {
                            if (MessageBox.Show("In chosen file format, only strokes can be saved. All other elements added to InkCanvas will be lost.\n Do you want to proceed? To save correctly your data, chose binary file(*.pak) instead.", "", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                            {
                                Strokes.Save(file);
                            }
                        }
                        //bitmap object
                        else
                        {
                            RenderTargetBitmap rtb = new RenderTargetBitmap((int)ActualWidth,
                                            (int)ActualHeight, 0, 0, PixelFormats.Default);

                            rtb.Render(this);
                            BmpBitmapEncoder encoder = new BmpBitmapEncoder();
                            encoder.Frames.Add(BitmapFrame.Create(rtb));
                            encoder.Save(file);
                        }

                        file.Close();
                    }
                }

            }
            catch (Exception exc)
            {
                if (extension.Contains("pak"))
                {
                    FileInfo[] fInfo = dInfo.GetFiles();

                    for (int j = 0; j < fInfo.Length; j++)
                    {
                        FileInfo fi = fInfo[j];
                        File.Delete(fi.FullName);
                    }

                    //Do not delete this.
                    //time for deleting files is needed.
                    //then delete directories
                    Thread.Sleep(300);

                    Directory.Delete(dInfo.FullName);
                }

                MessageBox.Show(exc.Message, "");
            }
        }

        private void SetSavedInfo(InkCanvasSerializationInfo info, string directory)
        {
            if (info == null)
                return;

            if (info.StrokesInfo != null)
            {
                StrokeCollection coll = GetStrokeCollectonFromSerializationInfo(info.StrokesInfo);
                Strokes.Add(coll);
            }

            if (info.Images != null)
            {
                foreach (SerializationBaseInfo ii in info.Images)
                {
                    CreateImage(ii, directory);
                }
            }

            if (info.MediaElements != null)
            {
                foreach (SerializationBaseInfo ii in info.MediaElements)
                {
                    CreateMediaPlayer(ii, directory);
                }
            }

            if (info.TextBoxes != null)
            {
                foreach (SerializationTextBoxInfo ii in info.TextBoxes)
                {
                    CreateTextBox(ii);
                }
            }

            if (!string.IsNullOrEmpty(info.Background))
            {
                BrushValueSerializer ser = new BrushValueSerializer();
                if (File.Exists(info.Background))
                {
                    BitmapImage bm = new BitmapImage();
                    bm.BeginInit();
                    bm.UriSource = new Uri(info.Background);
                    bm.CacheOption = BitmapCacheOption.OnLoad;
                    bm.EndInit();

                    ImageBrush br = new ImageBrush(bm);
                    Background = br;
                }
                else if (ser.CanConvertFromString(info.Background, null))
                {
                    Background = (Brush)ser.ConvertFromString(info.Background, null);
                }
            }
        }

        private InkCanvasSerializationInfo GetInkCanvasSerializationInfo(DirectoryInfo dInfo, out bool deleteFolder)
        {
            InkCanvasSerializationInfo info = new InkCanvasSerializationInfo();
            info.StrokesInfo = GetSerializationStrokesInfo(Strokes);

            List<SerializationBaseInfo> images = new List<SerializationBaseInfo>();
            List<SerializationBaseInfo> mediaElements = new List<SerializationBaseInfo>();
            List<SerializationTextBoxInfo> textBoxes = new List<SerializationTextBoxInfo>();

            string root = System.IO.Path.GetPathRoot(dInfo.FullName);

            long availableSpace = 0;
            long usedSpace = 0;
            DriveInfo[] allDrives = DriveInfo.GetDrives();
            foreach (DriveInfo d in allDrives)
            {
                if (d.Name == root)
                {
                    availableSpace = d.AvailableFreeSpace;
                    break;
                }
            }

            foreach (UIElement ui in Children)
            {
                if (ui is Image)
                {
                    Image im = ui as Image;
                    Uri originalFilePath = (im.Source != null ? (im.Source as BitmapImage).UriSource : new Uri(DEFAULT_IMAGE_PATH));

                    if (File.Exists(originalFilePath.LocalPath))
                    {
                        FileInfo i = new FileInfo(originalFilePath.LocalPath);
                        usedSpace += i.Length;
                    }
                }
                else if (ui is Grid)
                {
                    Grid g = ui as Grid;
                    MediaElement me = (MediaElement)g.Children[0];

                    if (me.Source == null)
                    {
                        continue;
                    }

                    Uri originalFilePath = string.IsNullOrEmpty(me.Source.LocalPath) ? new Uri("") : me.Source;
                    string currentFilePath = dInfo.FullName + "\\" + System.IO.Path.GetFileName(originalFilePath.LocalPath);

                    if (File.Exists(originalFilePath.LocalPath))
                    {
                        FileInfo i = new FileInfo(originalFilePath.LocalPath);
                        usedSpace += i.Length;
                    }
                }
            }

            deleteFolder = true;
            if (availableSpace < usedSpace)
            {
                MessageBox.Show("There is no enough space on the disc to save file.");
                return null;
            }

            List<string> existingFiles = new List<string>();
            foreach (UIElement ui in Children)
            {
                if (ui is Image)
                {
                    Image im = ui as Image;
                    SerializationBaseInfo ii = new SerializationBaseInfo();
                    ii.CanvasX = (double)im.GetValue(InkCanvas.LeftProperty);
                    ii.CanvasY = (double)im.GetValue(InkCanvas.TopProperty);
                    ii.Size = new Size(im.ActualWidth, im.ActualHeight);
                    ii.MediaRotationAngle = (im.LayoutTransform as RotateTransform).Angle;

                    Uri originalFilePath = (Uri)(im.Source != null ? (im.Source as BitmapImage).UriSource : new Uri(""));
                    string currentFilePath = dInfo.FullName + "\\" + System.IO.Path.GetFileName(originalFilePath.LocalPath);

                    if (File.Exists(originalFilePath.LocalPath))
                    {
                        if (originalFilePath.LocalPath != currentFilePath)
                        {
                            File.Copy(originalFilePath.LocalPath, currentFilePath, true);
                        }

                        existingFiles.Add(currentFilePath);
                        ii.FilePath = new Uri(currentFilePath);
                    }
                    else
                    {
                        ii.FilePath = new Uri(DEFAULT_IMAGE_PATH);
                    }

                    images.Add(ii);
                }
                else if (ui is Grid)
                {
                    Grid g = ui as Grid;
                    MediaElement me = (MediaElement)g.Children[0];
                    SerializationBaseInfo ii = new SerializationBaseInfo();
                    ii.CanvasX = (double)g.GetValue(InkCanvas.LeftProperty);
                    ii.CanvasY = (double)g.GetValue(InkCanvas.TopProperty);
                    ii.Size = new Size(g.ActualWidth, g.ActualHeight);
                    ii.MediaRotationAngle = (me.LayoutTransform as RotateTransform).Angle;

                    if (me.Source != null)
                    {
                        Uri originalFilePath = string.IsNullOrEmpty(me.Source.LocalPath) ? new Uri("") : me.Source;
                        string currentFilePath = dInfo.FullName + "\\" + System.IO.Path.GetFileName(originalFilePath.LocalPath);

                        if (originalFilePath.LocalPath != currentFilePath)
                        {
                            File.Copy(originalFilePath.LocalPath, currentFilePath, true);
                        }

                        existingFiles.Add(currentFilePath);
                        ii.FilePath = new Uri(currentFilePath);
                    }

                    mediaElements.Add(ii);
                }
                else if (ui is RichTextBox)
                {
                    RichTextBox tb = ui as RichTextBox;
                    SerializationTextBoxInfo ii = new SerializationTextBoxInfo();
                    ii.CanvasX = (double)tb.GetValue(InkCanvas.LeftProperty);
                    ii.CanvasY = (double)tb.GetValue(InkCanvas.TopProperty);
                    ii.Size = new Size(tb.ActualWidth, tb.ActualHeight);
                    ii.MediaRotationAngle = (tb.LayoutTransform as RotateTransform).Angle;

                    ii.FontFamilyName = tb.FontFamily.Source;
                    ii.FontSize = tb.FontSize;
                    ii.FontStyle = tb.FontStyle.GetHashCode();
                    ii.FontWeight = tb.FontWeight.ToOpenTypeWeight();
                    ii.FontStretch = tb.FontStretch.ToOpenTypeStretch();

                    BrushValueSerializer ser = new BrushValueSerializer();
                    if (ser.CanConvertToString(tb.Foreground, null))
                    {
                        ii.Foreground = ser.ConvertToString(tb.Foreground, null);
                    }

                    bool found = false;
                    List<int> decor = new List<int>();
                    TextDecorationCollection col = null;
                    foreach (UIElement el in Children)
                    {
                        if (el is RichTextBox)
                        {
                            foreach (Block b in ((RichTextBox)el).Document.Blocks)
                            {
                                if (b is Paragraph)
                                {
                                    found = true;
                                    col = ((Paragraph)b).TextDecorations;

                                    break;
                                }
                                else if (b is List)
                                {
                                    foreach (ListItem listItem in ((List)b).ListItems)
                                    {
                                        foreach (Block listBlock in listItem.Blocks)
                                        {
                                            if (listBlock is Paragraph)
                                            {
                                                found = true;
                                                col = ((Paragraph)listBlock).TextDecorations;

                                                break;
                                            }
                                        }

                                        if (found)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }

                            if (found)
                            {
                                break;
                            }
                        }
                    }

                    if (col != null && col.Count > 0)
                    {
                        foreach (TextDecoration td in col)
                        {
                            int result;
                            switch (td.Location)
                            {
                                case TextDecorationLocation.OverLine:

                                    result = 1;
                                    break;
                                case TextDecorationLocation.Strikethrough:

                                    result = 2;
                                    break;
                                case TextDecorationLocation.Underline:

                                    result = 0;
                                    break;
                                default:

                                    result = 3;
                                    break;
                            }

                            decor.Add(result);
                        }
                    }

                    ii.TextDecorations = decor;

                    XmlDocument xdoc = new XmlDocument();
                    xdoc.LoadXml(XamlWriter.Save(tb.Document));
                    ii.Text = xdoc.OuterXml;

                    textBoxes.Add(ii);
                }
            }

            info.Images = images.ToArray();
            info.MediaElements = mediaElements.ToArray();
            info.TextBoxes = textBoxes.ToArray();

            BrushValueSerializer bvs = new BrushValueSerializer();
            if (bvs.CanConvertToString(Background, null))
            {
                info.Background = bvs.ConvertToString(Background, null);
            }
            else if (Background is ImageBrush)
            {
                ImageBrush br = Background as ImageBrush;
                Uri originalFilePath = (Uri)(br.ImageSource != null ? (br.ImageSource as BitmapImage).UriSource : new Uri(""));
                string currentFilePath = dInfo.FullName + "\\" + System.IO.Path.GetFileName(originalFilePath.LocalPath);

                if (File.Exists(originalFilePath.LocalPath))
                {
                    if (originalFilePath.LocalPath != currentFilePath)
                    {
                        File.Copy(originalFilePath.LocalPath, currentFilePath, true);
                    }

                    existingFiles.Add(currentFilePath);
                    info.Background = currentFilePath;
                }
            }

            FileInfo[] fInfo = dInfo.GetFiles();
            foreach (FileInfo fi in fInfo)
            {
                if (!existingFiles.Contains(fi.FullName))
                {
                    File.Delete(fi.FullName);
                }
                else
                {
                    deleteFolder = false;
                }
            }

            return info;
        }

        private SerializationStrokesInfo GetSerializationStrokesInfo(StrokeCollection strokes)
        {
            byte[] rez = null;
            List<SerializationDrawingAttributesInfo> attrList = new List<SerializationDrawingAttributesInfo>();

            if (strokes.Count > 0)
            {
                InkCanvasAdvCustomStrokes customStrokes = new InkCanvasAdvCustomStrokes();
                customStrokes.StrokeCollection = new Point[strokes.Count][];

                for (int i = 0; i < strokes.Count; i++)
                {
                    Stroke stroke = strokes[i];
                    DrawingAttributes strokeAttr = stroke.DrawingAttributes;

                    SerializationDrawingAttributesInfo da = new SerializationDrawingAttributesInfo
                    {
                        ColorA = strokeAttr.Color.A,
                        ColorR = strokeAttr.Color.R,
                        ColorG = strokeAttr.Color.G,
                        ColorB = strokeAttr.Color.B,
                        Height = strokeAttr.Height,
                        Width = strokeAttr.Width,
                        FitToCurve = strokeAttr.FitToCurve,
                        IgnorePressure = strokeAttr.IgnorePressure,
                        IsHighlighter = strokeAttr.IsHighlighter
                    };
                    attrList.Add(da);

                    customStrokes.StrokeCollection[i] = new Point[stroke.StylusPoints.Count];
                    for (int j = 0; j < stroke.StylusPoints.Count; j++)
                    {
                        customStrokes.StrokeCollection[i][j] = new Point();

                        customStrokes.StrokeCollection[i][j].X = stroke.StylusPoints[j].X;
                        customStrokes.StrokeCollection[i][j].Y = stroke.StylusPoints[j].Y;
                    }
                }

                MemoryStream ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, customStrokes);

                rez = ms.GetBuffer();
            }

            return new SerializationStrokesInfo
            {
                StrokeCollection = rez,
                SerializationDrawingAttributesInfo = attrList.ToArray()
            };
        }

        private StrokeCollection GetStrokeCollectonFromSerializationInfo(SerializationStrokesInfo serializedInfo)
        {
            StrokeCollection coll = new StrokeCollection();

            if (serializedInfo.StrokeCollection != null && serializedInfo.StrokeCollection.Length > 0)
            {
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    MemoryStream ms = new MemoryStream(serializedInfo.StrokeCollection);

                    InkCanvasAdvCustomStrokes customStrokes = bf.Deserialize(ms) as InkCanvasAdvCustomStrokes;
                    List<SerializationDrawingAttributesInfo> attrList = new List<SerializationDrawingAttributesInfo>(serializedInfo.SerializationDrawingAttributesInfo);

                    for (int i = 0; i < customStrokes.StrokeCollection.Length; i++)
                    {
                        if (customStrokes.StrokeCollection[i] != null)
                        {
                            SerializationDrawingAttributesInfo info = attrList[i];
                            DrawingAttributes attr = new DrawingAttributes
                            {
                                Color = Color.FromArgb(info.ColorA, info.ColorR, info.ColorG, info.ColorB),
                                Height = info.Height,
                                Width = info.Width,
                                FitToCurve = info.FitToCurve,
                                IgnorePressure = info.IgnorePressure,
                                IsHighlighter = info.IsHighlighter
                            };

                            StylusPointCollection stylusCollection = new
                              StylusPointCollection(customStrokes.StrokeCollection[i]);
                            Stroke stroke = new Stroke(stylusCollection, attr);
                            StrokeCollection strokes = new StrokeCollection();
                            strokes.Add(stroke);

                            coll.Add(strokes);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            return coll;
        }

        #endregion //Implementation
    }
}
